package com.terran4j.kotlin.funs


/**************************  高阶函数： 4-10  ***************************/

fun plus(a: Int, b: Int): Int = a + b

fun minus(a: Int, b: Int): Int = a - b

fun calculate(array: Array<Int>, method: (a: Int, b: Int) -> Int): Int {
    if (array.isEmpty()) {
        return 0;
    }

    var result: Int? = null
    array.forEach {
        result = if (result == null) {
            it
        } else {
            method(result!!, it)
        }
//        result = result?.let { c -> method(c, it) } ?: it  // 这样写也行。
    }
    return result!!
}

fun doCalculate() {
    var result = calculate(arrayOf<Int>(1, 2, 3), ::plus)
    println("result = $result")
    result = calculate(arrayOf<Int>(1, 2, 3), ::minus)
    println("result = $result")
}

/**************************  Lambda表达式： 4-11  ***************************/

fun doLambda2() {
    // Lambda表达式 可以赋值给变量。
    var sum = { a: Int, b: Int -> a+b }
    var result = calculate(arrayOf<Int>(1, 2, 3), sum)
    println("result = $result")

    sum = { a: Int, b: Int ->
        println("a = $a, b = $b")
        a+b
    }
    result = calculate(arrayOf<Int>(1, 2, 3), sum)
    println("result = $result")

    // Lambda表达式作为参数传给高阶函数。
    result = calculate(arrayOf<Int>(1, 2, 3), { a, b -> a - b })
    println("result = $result")

    // 写清楚函数类型
    var max: (Int, Int) -> Int = { a, b -> if (a > b) a else b }
    result = calculate(arrayOf<Int>(1, 2, 3), max)
    println("result = $result")

    // 只有一个参数时，参数名可以省略，函数体中用 it 表示。
    var square: (Int) -> Int = { it * it }
    result = square(3)
    println("result = $result")
}